#!/usr/bin/env python
# -*- coding: utf-8 -*-

""" The gaeo controller module. 

Classes:
    Controller:
"""

import logging
from email.Utils import formatdate
import time
import urllib

# GAEO imports
from gaeo.session import Session

# App imports
import settings

class Controller(object):
    """
    The GAEO Controller class.
    
    """
    _rendered = False

    def __init__(self, request, response, params={}):
        '''
        Constructor
        '''
        self.request = request
        self.response = response
        self.params = params
        
        for k in self.request.arguments():
            self.params[k] = self.request.get_all(k)
            if len(self.params[k]) == 1:
                self.params[k] = self.params[k][0]
        
        self.params = self.__nested_params(self.params)
        self.cookies = request.cookies
        self.session = self._get_session()
        self.is_xhr = 'X_REQUESTED_WITH' in self.request.headers and \
            self.request.headers['X_REQUESTED_WITH'] == 'XMLHttpRequest'
        
        # initial the view instance
        try:
            module = __import__('gaeo.view',
                                globals(),
                                locals(),
                                settings.VIEW_CLASS,
                                -1)
            clz = module.__dict__.get(settings.VIEW_CLASS)
            self.view = clz(self)
        except ImportError, e:
            logging.error('Cannot initialize the view instance: %s', e)
            raise
    
        self.view.session = self.session
    
    def before_action(self):
        pass
    
    def after_action(self):
        pass
    
    def redirect(self, url, permanently=False):
        if permanently:
            self.response.set_status(301, 'Move Permanently')
        else:
            self.response.set_status(302, 'Found')
        self.response.headers['Location'] = url
        self.response.clear()
        self._rendered = True
    
    def output(self, *html):
        for h in html:
            self.response.out.write(h)
        self._rendered = True
    
    def set_no_render(self):
        self._rendered = True
        
    def json_output(self, json_data={}):
        from django.utils import simplejson
        self.response.headers['Content-Type'] = 'application/json'
        self.response.out.write(simplejson.dumps(json_data))
        self._rendered = True
        
    def complete(self):
        if not self._rendered:
            self.view.render()
    
    def set_cookie(self, name, value, max_age=None):
        cookie_data = [
            '%s=%s' % (name, value),
            'path=%s' % settings.SESSION_COOKIE_PATH
        ]
        if max_age is not None:
            rfcdate = formatdate(time.time() + max_age)
            expires = '%s-%s-%s GMT' % (rfcdate[:7], rfcdate[8:11], rfcdate[12:25])
            cookie_data.extend([
                'max_age=%s' % max_age,
                'expires=%s' % expires
            ])

        cookie_str = '; '.join(cookie_data)
        self.response.headers.add_header('Set-Cookie', cookie_str)
        logging.debug("Set-Cookie: %s" % cookie_str)
    
    def _get_session(self):
        session = None
        session_key = settings.SESSION_COOKIE_NAME
        if session_key in self.cookies:
            session = Session(key=self.cookies[session_key], 
                              controller=self)
        
        if session is None:
            session = Session(controller=self)
        
        return session
    
    def __appender(self, dict, arr, val):
        if len(arr) > 1:
            try:
                dict[arr[0]]
            except KeyError:
                dict[arr[0]] = {}
            return {arr[0]: self.__appender(dict[arr[0]], arr[1:], val)}
        else:
            dict[arr[0]] = val
            return

    def __nested_params(self, prm):
        prm2 = {}
        for param in prm:
            parray = param.replace(']', '').split('[')
            if len(parray) == 1:
                parray = parray[0].split('-')
            self.__appender(prm2, parray, prm[param])
        return prm2